﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;

namespace Web.Utility.WebCapture
{
    [Serializable]
    public class CaptureClass
    {
        /// <summary>
        /// 正则表达式过滤网页HTML（得到特定内容）
        /// </summary>
        /// <param name="content">原始内容</param>
        /// <param name="pattern">正则表达式</param>
        /// <param name="flage">正则表达式中子式名称</param>
        /// <returns>返回结果集</returns>
        public static List<string> GetContent(string content, string pattern, string flage)
        {
            if (!string.IsNullOrEmpty(content) && !string.IsNullOrEmpty(pattern))
            {
                MatchCollection mc = Regex.Matches(content, pattern, RegexOptions.IgnoreCase);
                List<string> strs = new List<string>();
                foreach (Match m in mc)
                {
                    strs.Add(m.Groups[flage].Value);
                }
                return strs;
            }
            return null;
        }

        /// <summary>
        /// 正则表达式过滤网页HTML（得到特定内容）
        /// </summary>
        /// <param name="content">原始内容</param>
        /// <param name="pattern">正则表达式</param>
        /// <returns>返回结果集</returns>
        public static List<string> GetContent(string content, string pattern)
        {
            if (!string.IsNullOrEmpty(content) && !string.IsNullOrEmpty(pattern))
            {
                MatchCollection mc = Regex.Matches(content, pattern, RegexOptions.IgnoreCase);
                List<string> strs = new List<string>();
                foreach (Match m in mc)
                {
                    strs.Add(m.Value);
                }
                return strs;
            }
            return null;
        }

        /// <summary>
        /// 正则表达式过滤网页HTML（得到特定内容）
        /// </summary>
        /// <param name="content">原始内容</param>
        /// <param name="pattern">正则表达式</param>
        /// <param name="flage">正则表达式中子式名称</param>
        /// <returns>返回结果</returns>
        public static string GetContentSingle(string content, string pattern, string flage)
        {
            if (!string.IsNullOrEmpty(content) && !string.IsNullOrEmpty(pattern))
            {
                Match m = Regex.Match(content, pattern, RegexOptions.IgnoreCase);
                {
                    return m.Groups[flage].Value;
                }
            }
            return string.Empty;
        }

        /// <summary>
        /// 正则表达式过滤网页HTML（得到特定内容）
        /// </summary>
        /// <param name="content">原始内容</param>
        /// <param name="pattern">正则表达式</param>
        /// <returns>返回结果</returns>
        public static string GetContentSingle(string content, string pattern)
        {
            if (!string.IsNullOrEmpty(content) && !string.IsNullOrEmpty(pattern))
            {
                Match m = Regex.Match(content, pattern, RegexOptions.IgnoreCase);
                {
                    return m.Value;
                }
            }
            return string.Empty;
        }

        /// <summary>
        /// 获取网页内容（整个页面的html）
        /// </summary>
        /// <param name="url">网页地址URL</param>
        /// <param name="encoding">网页编码</param>
        /// <returns>返回网页html(失败则为空字符)</returns>
        public static string GetPage(string url, Encoding encoding)
        {
            HttpWebRequest request;
            HttpWebResponse response = null;
            StreamReader reader = null;
            try
            {
                request = (HttpWebRequest)WebRequest.Create(url);
                request.Timeout = 5000;//5秒没有反应就退出
                request.AllowAutoRedirect = false;
                request.UserAgent = "Mozilla/5.0 (Windows; U; Windows NT 6.1; zh-CN; rv:1.9.2) Gecko/20100115 Firefox/3.6";
                request.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
                //request.Connection = "keep-alive";
                //request.KeepAlive = true;
                response = (HttpWebResponse)request.GetResponse();
                if (response.StatusCode == HttpStatusCode.OK)
                {
                    reader = new StreamReader(response.GetResponseStream(), encoding);
                    return reader.ReadToEnd();
                }
            }
            catch
            {
            }
            finally
            {
                if (response != null)
                {
                    response.Close();
                }
                if (reader != null)
                {
                    reader.Close();
                }
            }
            return string.Empty;
        }

        /// <summary>
        /// 获取网页内容（整个页面的html）
        /// </summary>
        /// <param name="url">网页地址URL</param>
        /// <returns>返回网页html(失败则为空字符)</returns>
        public static string GetPage(string url)
        {
            return GetPage(url, Encoding.Default);
        }

        /// <summary>
        /// 正则表达式 字符串替换（符合正则表达式的都替换为给定内容）不区分大小写
        /// </summary>
        /// <param name="str">原始字符串</param>
        /// <param name="pattern">替换正则表达式规则（将要被替换字符串）</param>
        /// <param name="str_rep">替换字符串</param>
        /// <returns>返回替换后的字符串</returns>
        public static string StrReplace(string str, string pattern, string str_rep)
        {
            if (!string.IsNullOrEmpty(pattern))
            {
                Regex regex = new Regex(pattern, RegexOptions.Multiline | RegexOptions.IgnoreCase);
                str = regex.Replace(str, str_rep);
                return str;
            }
            return null;
        }

        /// <summary>
        /// 过滤HTML
        /// </summary>
        /// <param name="str"></param>
        /// <param name="pattern"></param>
        /// <returns></returns>
        public static string HtmlFilter(string str, string pattern)
        {
            if (string.IsNullOrEmpty(str) || string.IsNullOrEmpty(pattern))
            {
                return null;
            }
            switch (pattern)
            {
                case "<table":
                    pattern = @"<\s*?table[\s\S]*?>";//<table>
                    str = StrReplace(str, pattern, "");
                    pattern = @"<\s*?/\s*?table\s*?>";//</table>
                    str = StrReplace(str, pattern, "");
                    break;
                case "<tr":
                    pattern = @"<\s*?tr[\s\S]*?>";//<tr>
                    str = StrReplace(str, pattern, "");
                    pattern = @"<\s*?/\s*?tr\s*?>";//<tr>
                    str = StrReplace(str, pattern, "");
                    break;
                case "<td":
                    pattern = @"<\s*?(td|th)[\s\S]*?>";//<td>
                    str = StrReplace(str, pattern, "");
                    pattern = @"<\s*?/\s*?(td|th)\s*?>";//</td>
                    str = StrReplace(str, pattern, "");
                    break;
                case "<all":
                    pattern = @"<\/*[^<>]*>";//所有标签
                    str = StrReplace(str, pattern, "");
                    break;
                case "<dl":
                    pattern = @"<\s*?dl\s*?>";//清单<dl>
                    str = StrReplace(str, pattern, "");
                    pattern = @"<\s*?(dd|dt)\s*?>";//清单内容<dd> 清单标题<dt>
                    str = StrReplace(str, pattern, "");
                    break;
                case "<form":
                    pattern = @"<\s*?form[\s\S]*?>";//<form>
                    str = StrReplace(str, pattern, "");
                    break;
                case "<frame":
                    pattern = @"<\s*?frame[\s\S]*?>";//<frame>
                    str = StrReplace(str, pattern, "");
                    pattern = @"<\s*?iframe[\s\S]*?>";//<iframe>
                    str = StrReplace(str, pattern, "");
                    break;
                case "<sub":
                    pattern = @"<\s*?(sub|sup)\s*?>";//<sub><sup>
                    str = StrReplace(str, pattern, "");
                    break;
                case "<a":
                    pattern = @"<\s*?a[\s\S]*?>";//<a>
                    str = StrReplace(str, pattern, "");
                    pattern = @"<\s*?/\s*?a\s*?>";//</a>
                    str = StrReplace(str, pattern, "");
                    break;
                case "<img":
                    pattern = @"<\s*?img[\s\S]*?>";//<img>
                    str = StrReplace(str, pattern, "");
                    break;
                case "<input":
                    pattern = @"<\s*?input[\s\S]*?>";//<input/>
                    str = StrReplace(str, pattern, "");
                    break;
                case "<p":
                    pattern = @"<\s*?p[\s\S]*?>";//<p> 
                    str = StrReplace(str, pattern, "");
                    pattern = @"<\s*?/\s*?p\s*?>";//<p>
                    str = StrReplace(str, pattern, "");
                    break;
                case "<script":
                    pattern = @"<\s*?script[\s\S]*?>[\s\S]*?<\s*?/\s*?script>";//SCRIPT
                    str = StrReplace(str, pattern, "");
                    break;
                case "<font":
                    pattern = @"<\s*?font[\s\S]*?>";//<font>
                    str = StrReplace(str, pattern, "");
                    pattern = @"<\s*?/\s*?font\s*?>";//</font>
                    str = StrReplace(str, pattern, "");
                    break;
                case "<br":
                    pattern = @"<\s*?br\s+/?>";//<br><br/>
                    str = StrReplace(str, pattern, "");
                    break;
                case "<li":
                    pattern = @"<\s*?(li|ul|ol)[\s\S]*?>";//<li><ul><ol>
                    str = StrReplace(str, pattern, "");
                    pattern = @"<\s*?/\s*?(li|ul|ol)\s*?>";//</li></ul></ol>
                    str = StrReplace(str, pattern, "");
                    break;
                case "<hr":
                    pattern = @"<\s*?hr\s*?>";//<hr>
                    str = StrReplace(str, pattern, "");
                    break;
                case "<div":
                    pattern = @"<\s*?div[\s\S]*?>";//<div>
                    str = StrReplace(str, pattern, "");
                    pattern = @"<\s*?/\s*?div\s*?>";//</div>
                    str = StrReplace(str, pattern, "");
                    break;
                case "<span":
                    pattern = @"<\s*?span[\s\S]*?>";//<span>
                    str = StrReplace(str, pattern, "");
                    pattern = @"<\s*?/\s*?span\s*?>";//</span>
                    str = StrReplace(str, pattern, "");
                    break;
                case "<h1":
                    pattern = @"<\s*?h\d[\s\S]*?>";//<h1-7>
                    str = StrReplace(str, pattern, "");
                    pattern = @"<\s*?/\s*?h\d\s*?>";//</h1-7>
                    str = StrReplace(str, pattern, "");
                    break;
                case "<tbody":
                    pattern = @"<\s*?tbody[\s\S]*?>";//<tbody>表格体
                    str = StrReplace(str, pattern, "");
                    pattern = @"<\s*?/\s*?tbody\s*?>";//</tbody>
                    str = StrReplace(str, pattern, "");
                    break;
                case "<b":
                    pattern = @"<\s*?(b\s*?|strong[\s\S]*?)>";//<b><strong>
                    str = StrReplace(str, pattern, "");
                    pattern = @"<\s*?/\s*?(b|strong)\s*?>";//</b></strong>
                    str = StrReplace(str, pattern, "");
                    break;
                case "<em":
                    pattern = @"<\s*?(i\s*?|em\s*?)>";//斜体<em><i>
                    str = StrReplace(str, pattern, "");
                    pattern = @"<\s*?/\s*?(em|i)\s*?>";//斜体</em></i>
                    str = StrReplace(str, pattern, "");
                    break;
                case "<nbsp":
                    pattern = @"([\r\n])[\s]+";//除&nbsp 所有空格符(包括换行) 
                    str = StrReplace(str, pattern, "");
                    break;
                default:
                    break;
            }
            return str;
        }

        /// <summary>
        /// 获取网页内容[html]（循环次数=k-j）
        /// </summary>
        /// <param name="url">网页地址URL</param>
        /// <param name="j">异常后循环次数开始值</param>
        /// <param name="k">异常后循环次数结束值</param>
        /// <returns>返回网页html(失败则为空字符)</returns>
        public static string GetUrlResponse(string url, int j, int k)
        {
            HttpWebRequest request;
            HttpWebResponse response = null;
            StreamReader reader = null;
            try
            {
                request = (HttpWebRequest)WebRequest.Create(url);
                //request.UserAgent = "www.svnhost.cn";
                request.Timeout = 5000;//5秒没有反应就退出
                request.AllowAutoRedirect = false;

                response = (HttpWebResponse)request.GetResponse();
                Encoding encoding;
                encoding = Encoding.GetEncoding(response.ContentEncoding != "" ? response.ContentEncoding : "GB2312");
                if (response.StatusCode == HttpStatusCode.OK)
                {
                    reader = new StreamReader(response.GetResponseStream(), encoding);
                    string html = reader.ReadToEnd();
                    return html;
                }
            }
            catch
            {
                j = j + 1;
                if (j <= k)
                {
                    GetUrlResponse(url, j, k);
                }
            }
            finally
            {

                if (response != null)
                {
                    response.Close();
                }
                if (reader != null)
                    reader.Close();
            }

            return string.Empty;
        }

        /// <summary>
        /// 获取网页返回的cookies
        /// </summary>
        /// <param name="url">网页地址URL</param>
        /// <param name="cookieName">cookie名称</param>
        /// <returns>返回该cookie的值</returns>
        public static string GetCookies(string url, string cookieName)
        {
            try
            {
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);

                request.CookieContainer = new CookieContainer();

                request.CookieContainer.SetCookies(new Uri(url), cookieName);

                HttpWebResponse response = (HttpWebResponse)request.GetResponse();

                return response.Headers["Set-Cookie"];
            }
            catch
            {
            }
            return string.Empty;
        }

        /// <summary>
        /// post页面，得到post传回来的值
        /// </summary>
        /// <param name="strURL">要post的页面</param>
        /// <param name="strArgs">post参数字符串（简单的例子直接用Firefox得到的post数据做测试）</param>
        /// <returns>返回得到的字符串</returns>
        public static string PublishArticle(string strURL, string strArgs)
        {
            try
            {
                HttpWebRequest myHttpWebRequest = (HttpWebRequest)WebRequest.Create(strURL);
                myHttpWebRequest.ContentType = "text/html";
                myHttpWebRequest.Method = "Post";

                myHttpWebRequest.AllowAutoRedirect = true;
                myHttpWebRequest.KeepAlive = true;
                myHttpWebRequest.UserAgent = "Mozilla/5.0 (Windows; U; Windows NT 6.1; zh-CN; rv:1.9.2) Gecko/20100115 Firefox/3.6";
                myHttpWebRequest.Accept = "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/msword, application/x-shockwave-flash, */*";
                myHttpWebRequest.ContentType = "application/x-www-form-urlencoded";
                myHttpWebRequest.Method = "POST";
                myHttpWebRequest.Headers.Add("cookie:" + null);//cookie值

                Encoding charset;
                charset = strArgs.Contains("UTF-8") ? Encoding.GetEncoding("UTF-8") : Encoding.Default;

                Stream MyRequestStrearm = myHttpWebRequest.GetRequestStream();
                StreamWriter MyStreamWriter = new StreamWriter(MyRequestStrearm, charset);
                //把数据写入HttpWebRequest的Request流
                MyStreamWriter.Write(strArgs);
                //关闭打开对象 
                MyStreamWriter.Close();
                MyRequestStrearm.Close();

                HttpWebResponse response = (HttpWebResponse)myHttpWebRequest.GetResponse();

                StreamReader sr = new StreamReader(response.GetResponseStream(), Encoding.GetEncoding("gb2312"));
                string strResult = sr.ReadToEnd();
                return strResult;
            }
            catch
            {
                return string.Empty;
            }
        }

    }
}
